<?php
/**
 * Jishupu-Laravel-Vue-Admin
 * @Author:技术铺<jishupu@qq.com>
 * @Date: 2021/11/11
 */

namespace App\Http\Requests;

use App\Models\Permission;
use App\Services\DictionaryService;
use App\Services\RouteService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;

/**
 * 权限模块表单验证
 * Class PermissionRequest
 * @package App\Http\Requests
 */
class PermissionRequest extends BaseRequest
{

    /**
     * 注入表单请求验证时自动校验
     *
     * @var bool
     */
    public $autoValidate = false;

    /**
     * 当前经过身份验证的用户是否可以执行请求操作
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * 规则
     *
     * @return array
     */
    public function rules()
    {
        $permission = $this->permission;
        return [
            'id' => 'required|integer',
            'created_user_id' => 'required|integer',
            'type' => [
                'required',
                'integer',
                Rule::in(DictionaryService::getItemsValuesArray('permissionTypeVar')),
            ],
            'public_type' => [
                'required',
                'integer',
                Rule::in(DictionaryService::getItemsValuesArray('permissionPublicTypeVar')),
            ],
            'parent_id' => [
                'required',
                'integer',
                function ($attribute, $value, $fail) {
                    if ($this->type == 2 && $value == 0) {
                        $fail(__('permission.please_create_controller'));
                    }
                }
            ],
            'name' => "required|min:2|max:30",
            'priv' => ['nullable', 'required_if:type,2', 'max:200',
                Rule::unique('permission')->ignore($permission)->where(function ($query) {
                    return $query->where('deleted_at', null);
                }),
                function ($attribute, $value, $fail) use ($permission) {
                    if (!$this->validatePermission()) {
                        $fail(__('permission.not_exist_priv'));
                    }
                }
            ],
            'uri' => 'nullable',
            'request_methods' => 'nullable',
            'controller' => [
                'nullable',
                'max:255',
                function ($attribute, $value, $fail) use ($permission) {
                    if (!$this->validateController()) {
                        $fail(__('permission.not_exist_controller'));
                    }
                    if ($this->type == 1) {
                        $tmpPermission = Permission::where('type', 1)->where('controller', $value)->where('id', '!=', $permission->id ?? 0)->first();
                        if ($tmpPermission) {
                            $fail(__('permission.exist_controller'));
                        }
                    }
                }
            ],
            'controller_method' => 'nullable',
            'description' => 'nullable|max:200',
            'sort' => 'required|integer',
            'sort.*.id' => 'required|integer',
            'sort.*.sort' => 'required|integer',
        ];
    }


    /**
     * 定义场景
     * @var \string[][]
     */
    public $scenes = [
        'store' => [
            'created_user_id',
            'type',
            'public_type',
            'parent_id',
            'name',
            'priv',
            'uri',
            'request_methods',
            'controller',
            'controller_method',
            'description',
            'sort',
        ],
        'update' => [
            'parent_id',
            'type',
            'public_type',
            'name',
            'priv',
            'uri',
            'request_methods',
            'controller',
            'controller_method',
            'description',
            'sort',
        ],
        'destroy' => ['id'],
        'updateSort' => ['sort.*.id', 'sort.*.sort']
    ];

    /**
     * 验证错误的自定义属性
     *
     * @return array
     */
    public function attributes()
    {
        return [
            'id' => __('common.id'),
            'type' => __('common.type'),
            'public_type' => __('permission.public_type'),
            'parent_id' => __('permission.parent_id'),
            'name' => __('permission.name'),
            'priv' => __('permission.priv'),
            'uri' => __('permission.uri'),
            'controller' => __('permission.controller'),
            'request_methods' => __('permission.request_methods'),
            'description' => __('permission.description'),
            'sort' => __('common.sort'),
            'status' => __('common.status'),
            'sort.*.id' => __('common.id'),
            'sort.*.sort' => __('common.sort'),
        ];
    }

    /**
     * 验证前
     *
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->offsetSet('created_user_id', Auth::id());
        $this->offsetSet('parent_id', 0);
        if ($this->type == 1) {
            $empty = ['priv', 'uri', 'request_methods', 'controller_method'];
            foreach ($empty as $field) $this->offsetSet($field, '');
            $this->offsetSet('public_type', 0);
        } else if ($this->type == 2) {
            $this->offsetSet('public_type', $this->public_type ?? 0);
            $getRouteByName = RouteService::getRouteByName($this->priv);
            $this->offsetSet('uri', $getRouteByName ? $getRouteByName['uri'] : "");
            $this->offsetSet('request_methods', $getRouteByName ? $getRouteByName['methods'] : "");
            $this->offsetSet('controller', $getRouteByName ? $getRouteByName['controller'] : "");
            $this->offsetSet('controller_method', $getRouteByName ? $getRouteByName['controller_method'] : "");
            //权限的父级处理
            if (isset($getRouteByName['controller']) && !empty($getRouteByName['controller'])) {
                $tmpPermission = Permission::where('type', 1)->where('controller', $getRouteByName['controller'])->first();
                $this->offsetSet('parent_id', $tmpPermission ? $tmpPermission['id'] : 0);
            }
        }
    }


    /**
     * 检验权限是否存在
     * @return bool
     */
    public function validatePermission()
    {
        $getRouteByName = RouteService::getRouteByName($this->priv);
        if (!$getRouteByName) {
            return false;
        }
        return true;
    }

    /**
     * 检验所属模块是否存在
     * @return bool
     */
    public function validateController()
    {
        $getRouteByController = RouteService::getRouteByController($this->controller);
        if (!$getRouteByController) {
            return false;
        }
        return true;
    }


    /**
     * 提示信息
     * @return array
     */
    public function messages()
    {
        return [
        ];
    }
}


